package com.example.simplesvc;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;
import java.util.List;
import java.util.Timer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@Configuration
public class ExampleConfiguration {

    private static Logger log = LoggerFactory.getLogger(ExampleConfiguration.class);

    @Bean
    @Qualifier("coreExecutor")
    public ExecutorService executor() {
        return Executors.newFixedThreadPool(10);
    }

    @Bean
    @Qualifier("extExecutor")
    public ExecutorService extExecutor() {
        return Executors.newFixedThreadPool(10);
    }

    @Bean
    @Qualifier("coreTimer")
    public Timer timer() {
        return new Timer();
    }

    @Bean
    public DisposableBean resourceCleaner(@Qualifier("coreExecutor") ExecutorService coreExecutor, @Qualifier("extExecutor") ExecutorService extExecutor, @Qualifier("coreTimer") Timer timer) {

        return new DisposableBean() {
            @Override
            public void destroy() throws Exception {
                try {
                    timer.cancel();
                } catch (Exception e) {
                    log.warn("终止timer异常", e);
                }

                List<ExecutorService> executorServiceList = Arrays.asList(coreExecutor, extExecutor);
                ExecutorService exec = Executors.newFixedThreadPool(executorServiceList.size() + 1);

                executorServiceList
                        .stream()
                        .forEach(x -> {
                            exec.submit(new Runnable() {
                                @Override
                                public void run() {
                                    try {
                                        shutdownExecutor(x);
                                    } catch (Exception e) {
                                        log.warn("终止线程池异常", e);
                                    }
                                }
                            });
                        });

                try {
                    // 等正在执行的任务执行完毕
                    if (!exec.awaitTermination(15, TimeUnit.SECONDS)) {
                        exec.shutdownNow(); // 取消当前正在执行的任务
                        //等待任务取消
                        if (!exec.awaitTermination(10, TimeUnit.SECONDS)) {
                            log.warn("Pool did not terminate");
                        }
                    }
                } catch (InterruptedException ie) {
                    // 若当前线程在等待结束是被打断，重新取消正在执行的任务
                    exec.shutdownNow();
                }


            }
        };


    }

    private void shutdownExecutor(ExecutorService pool) {
        pool.shutdown(); // 停止新任务提交
        try {
            // 等正在执行的任务执行完毕
            if (!pool.awaitTermination(10, TimeUnit.SECONDS)) {
                pool.shutdownNow(); // 取消当前正在执行的任务
                //等待任务取消
                if (!pool.awaitTermination(10, TimeUnit.SECONDS)) {
                    log.warn("Pool did not terminate");
                }
            }
        } catch (InterruptedException ie) {
            // 若当前线程在等待结束是被打断，重新取消正在执行的任务
            pool.shutdownNow();
        }
    }
}
